package com.jessechanrui.template.core.infrastructure;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.lang.reflect.Field;

/**
 * @author chenrui
 * @version 1.0
 * @description ColumnJacksonTypeHandler
 * @date 2025/5/26
 */
@MappedTypes({Object.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
@Slf4j
public class ColumnJacksonTypeHandler extends AbstractJsonTypeHandler<Object> {
    private static ObjectMapper OBJECT_MAPPER;

    public ColumnJacksonTypeHandler(Class<?> type) {
        super(type);
    }

    public ColumnJacksonTypeHandler(Class<?> type, Field field) {
        super(type, field);
    }

    public Object parse(String json) {
        ObjectMapper objectMapper = getObjectMapper();
        TypeFactory typeFactory = objectMapper.getTypeFactory();
        JavaType javaType = typeFactory.constructType(this.getFieldType());

        try {
            return objectMapper.readValue(json, javaType);
        } catch (JacksonException var6) {
            JacksonException e = var6;
            log.error("deserialize json: " + json + " to " + javaType + " error ", e);
            throw new RuntimeException(e);
        }
    }

    public String toJson(Object obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (JsonProcessingException var3) {
            JsonProcessingException e = var3;
            log.error("serialize " + obj + " to json error ", e);
            throw new RuntimeException(e);
        }
    }

    public static ObjectMapper getObjectMapper() {
        if (null == OBJECT_MAPPER) {
            OBJECT_MAPPER = new ObjectMapper();
            // 启用注解扫描
            OBJECT_MAPPER.findAndRegisterModules();
            // 忽略未知字段
            OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }

        return OBJECT_MAPPER;
    }

    public static void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "ObjectMapper should not be null", new Object[0]);
        OBJECT_MAPPER = objectMapper;
    }
}
